using System;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using Accona.Remoting.Remoting;

namespace Accona.Remoting.Multicast
{
    public class MulticastReceiver : IReceiver
    {
        private readonly Socket s;
        private readonly Guid senderId;
        private bool running = true;

        public MulticastReceiver(Guid applicationId)
        {
            senderId = senderId;
        }

        public MulticastReceiver(string mcastGroup, int port)
        {
            s = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
            s.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);

            var ipep = new IPEndPoint(IPAddress.Any, port);
            s.Bind(ipep);

            IPAddress ip = IPAddress.Parse(mcastGroup);

            s.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership,
                              new MulticastOption(ip, IPAddress.Any));

            var thread = new Thread(Receive)
                             {
                                 IsBackground = true
                             };
            thread.Start();
        }

        #region IReceiver Members

        public event Action<byte[]> OnMessage;

        #endregion

        private void InvokeOnMessage(byte[] msg)
        {
            Action<byte[]> handler = OnMessage;
            if (handler != null) handler(msg);
        }

        private void Receive()
        {
            var b = new byte[1400];
            while (running)
            {
                s.Receive(b);
                InvokeOnMessage(b);
            }
        }

        public void Stop()
        {
            running = false;
            s.Close();
        }
    }
}